package dongshi.daddy.stream;

import dongshi.daddy.stream.help.UserDTO;
import org.junit.Test;

import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

public class StreamTest {
    @Test
    public void toHashSet() {
        List<UserDTO> userList = getUserList();
        Stream<UserDTO> usersStream = userList.stream();
        HashSet<UserDTO> usersHashSet = usersStream.collect(Collectors.toCollection(HashSet::new));
        HashSet<UserDTO> usersHashSet1 = userList.stream().collect(Collectors.toCollection(() -> new HashSet<>()));
        System.out.println(usersHashSet);
        System.out.println(usersHashSet1);
    }

    @Test
    public void toSet() {
        List<UserDTO> userList = getUserList();
        Stream<UserDTO> usersStream = userList.stream();
        Set<UserDTO> usersSet = usersStream.collect(Collectors.toSet());
        System.out.println(usersSet);
    }

    @Test
    public void toArrayList() {
        List<UserDTO> userList = getUserList();
        Stream<UserDTO> usersStream = userList.stream();
        ArrayList<UserDTO> usersArrayList = usersStream.collect(Collectors.toCollection(ArrayList::new));
        System.out.println(usersArrayList);
    }

    @Test
    public void toObjectArr() {
        List<UserDTO> userList = getUserList();
        Stream<UserDTO> usersStream = userList.stream();
        Object[] objects = usersStream.toArray();
        System.out.println(objects);
    }

    @Test
    public void toUserDTOArr() {
        List<UserDTO> userList = getUserList();
        Stream<UserDTO> usersStream = userList.stream();
        UserDTO[] users = usersStream.toArray(UserDTO[]::new);
        for (UserDTO user : users) {
            System.out.println(user.toString());
        }
    }

    @Test
    public void max() {
        List<UserDTO> userList = getUserList();
        Stream<UserDTO> usersStream = userList.stream();
        Optional<UserDTO> maxUserOptional =
                usersStream.max((s1, s2) -> s1.getAge() - s2.getAge());
        if (maxUserOptional.isPresent()) {
            UserDTO masUser = maxUserOptional.get();
            System.out.println(masUser.toString());
        }

        List<UserDTO> userList1 = getUserList();
        Stream<UserDTO> usersStream1 = userList1.stream();
        Optional<UserDTO> maxUserOptionalNew = usersStream1.max(Comparator.comparingInt(UserDTO::getAge));
        if (maxUserOptionalNew.isPresent()) {
            UserDTO masUser = maxUserOptionalNew.get();
            System.out.println(masUser.toString());
        }

    }

    @Test
    public void min() {
        Optional<UserDTO> minUserOptional = getUserList().stream().min(Comparator.comparingInt(UserDTO::getAge));
        if (minUserOptional.isPresent()) {
            UserDTO minUser = minUserOptional.get();
            System.out.println(minUser.toString());
        }

        Optional<UserDTO> min = getUserList().stream().collect(Collectors.minBy((s1, s2) -> s1.getAge() - s2.getAge()));
        System.out.println(min.get());
    }

    @Test
    public void avg() {
        List<UserDTO> userList = getUserList();
        Stream<UserDTO> usersStream = userList.stream();
        Double avgScore = usersStream.collect(Collectors.averagingInt(UserDTO::getAge));
        System.out.println(avgScore);
    }

    @Test
    public void sum() {
        Integer reduceAgeSum = getUserList().stream().map(UserDTO::getAge).reduce(0, Integer::sum);
        System.out.println(reduceAgeSum);
        int ageSumNew = getUserList().stream().mapToInt(UserDTO::getAge).sum();
        System.out.println(ageSumNew);
    }
    @Test
    public void count() {
        long countNew = getUserList().stream().count();
        System.out.println(countNew);
    }

    @Test
    public void groupByAge() {
        //按照具体年龄分组
        Map<Integer, List<UserDTO>> ageGroupMap = getUserList().stream().collect(Collectors.groupingBy((UserDTO::getAge)));
        System.out.println(ageGroupMap);
    }

    @Test
    public void groupByGender() {
        //按照性别 分为"男"一组  "女"一组
        Map<Integer, List<UserDTO>> groupMap = getUserList().stream().collect(Collectors.groupingBy(s -> {
            if (s.getSex().equals("男")) {
                return 1;
            } else {
                return 0;
            }
        }));
        System.out.println(groupMap);
    }

    // Map<Integer, Map<String, Map<Integer, List<UserDTO>>>>
    @Test
    public void groupByAgeAndThenGender() {
        Map<Integer, Map<String, Map<Integer, List<UserDTO>>>> moreGroupMap = getUserList().stream().collect(Collectors.groupingBy(

                //1.KEY(Integer)             VALUE (Map<String, Map<Integer, List<UserDTO>>)
                UserDTO::getAge, Collectors.groupingBy(
                        //2.KEY(String)             VALUE (Map<Integer, List<UserDTO>>)
                        UserDTO::getSex, Collectors.groupingBy((userDTO) -> {
                            if (userDTO.getSex().equals("男")) {
                                return 1;
                            } else {
                                return 0;
                            }
                        }))));
        System.out.println(moreGroupMap);
    }

    private static List<UserDTO> getUserList() {
        UserDTO userDTO = new UserDTO();
        userDTO.setName("小冬");
        userDTO.setAge(18);
        userDTO.setSex("男");
        userDTO.setHasOrientation(false);
        UserDTO userDTO2 = new UserDTO();
        userDTO2.setName("小秋");
        userDTO2.setAge(30);
        userDTO2.setSex("男");
        userDTO2.setHasOrientation(true);
        UserDTO userDTO3 = new UserDTO();
        userDTO3.setName("春");
        userDTO3.setAge(18);
        userDTO3.setSex("女");
        userDTO3.setHasOrientation(true);
        List<UserDTO> userList = new ArrayList<>();
        userList.add(userDTO);
        userList.add(userDTO2);
        userList.add(userDTO3);
        return userList;
    }

}
